home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Storage / LinkSrcB.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  31.1 KB  |  1,088 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        LinkSrcB.cpp
  3.  
  4.     Contains:    Implementation of ODBaseLinkSource class
  5.  
  6.     Owned by:    Craig Carper
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <4>     9/26/96    CC        1391203: Eliminated RemovePromisedContent;
  13.                                     use ClearAllPromises instead.
  14.          <3>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  15.          <2>     3/26/96    CC        1332880: kODLinkContent should use std ISO
  16.                                     prefix.
  17.  
  18.     To Do: 
  19.     In Progress:
  20.         
  21. */
  22.  
  23. #define VARIABLE_MACROS
  24.  
  25. #define ODBaseLinkSource_Class_Source
  26. #include <LinkSrcB.xih>
  27.  
  28. #include <LinkSrc.xh>
  29.  
  30. #ifndef _EXCEPT_
  31. #include <Except.h>
  32. #endif
  33.  
  34. #ifndef _ODMEMORY_
  35. #include <ODMemory.h>
  36. #endif
  37.  
  38. #ifndef _CONSTDEF_
  39. #include <ConstDef.h>
  40. #endif
  41.  
  42. #ifndef SOM_ODLink_xh
  43. #include <Link.xh>
  44. #endif
  45.  
  46. #ifndef _LINKDLGS_
  47. #include <LinkDlgs.h>
  48. #endif
  49.  
  50. #ifndef SOM_ODPart_xh
  51. #include <Part.xh>
  52. #endif
  53.  
  54. #ifndef SOM_ODFrame_xh
  55. #include <Frame.xh>
  56. #endif
  57.  
  58. #ifndef SOM_ODContainer_xh
  59. #include <ODCtr.xh>
  60. #endif
  61.  
  62. #ifndef SOM_ODDocument_xh
  63. #include <Document.xh>
  64. #endif
  65.  
  66. #ifndef SOM_ODDraft_xh
  67. #include <Draft.xh>
  68. #endif
  69.  
  70. #ifndef SOM_ODSession_xh
  71. #include <ODSessn.xh>
  72. #endif
  73.  
  74. #ifndef SOM_ODArbitrator_xh
  75. #include <Arbitrat.xh>
  76. #endif
  77.  
  78. #ifndef SOM_ODWindowState_xh
  79. #include <WinStat.xh>
  80. #endif
  81.  
  82. #ifndef SOM_Module_OpenDoc_Foci_defined
  83. #include <Foci.xh>
  84. #endif
  85.  
  86. #ifndef SOM_ODStorageSystem_xh
  87. #include <ODStor.xh>
  88. #endif
  89.  
  90. #ifndef SOM_ODStorageUnit_xh
  91. #include <StorageU.xh>
  92. #endif
  93.  
  94. #ifndef SOM_Module_OpenDoc_StdProps_defined
  95. #include <StdProps.xh>
  96. #endif
  97.  
  98. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  99. #include <StdTypes.xh>
  100. #endif
  101.  
  102. #ifndef __ERRORS__
  103. #include <Errors.h>
  104. #endif
  105.  
  106. #ifndef _ODUTILS_
  107. #include <ODUtils.h>
  108. #endif
  109.  
  110. /* Adkins -- added to provide prototype for ODUnused and LMGetBufPtr */
  111. /* Adkins -- LMGetBufPtr is in LowMem.h, which PlfmDef.h conditionaly includes */
  112. #ifndef _PLFMDEF_
  113. #include <PlfmDef.h>
  114. #endif
  115.  
  116. #ifndef _ISOSTR_
  117. #include <ISOStr.h>
  118. #endif
  119.  
  120. #ifndef _DOCUTILS_
  121. #include <DocUtils.h>
  122. #endif
  123.  
  124. #ifndef _STDTYPIO_
  125. #include <StdTypIO.h>
  126. #endif
  127.  
  128. #ifndef _ODDEBUG_
  129. #include <ODDebug.h>
  130. #endif
  131.  
  132. #ifndef _POUTILS_
  133. #include <POUtils.h>
  134. #endif
  135.  
  136. #ifndef SOM_ODTypeList_xh
  137. #include <TypeList.xh>
  138. #endif
  139.  
  140. #ifndef SOM_LinkMgr_xh
  141. #include <LinkMgr.xh>
  142. #endif
  143.  
  144. #ifndef SOM_ODTypeListIterator_xh
  145. #include <TypLsItr.xh>
  146. #endif
  147.  
  148. #ifndef _STORUTIL_
  149. #include <StorUtil.h>
  150. #endif
  151.  
  152. #ifndef _TEMPOBJ_
  153. #include "TempObj.h"
  154. #endif
  155.  
  156. #pragma segment ODBaseLinkSource
  157.  
  158. //==============================================================================
  159. // Constants
  160. //==============================================================================
  161.  
  162. const    ODType    kODLinkContent    = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:ObjectType:LinkContent";
  163. const    ODULong    kODNullKey         = 0;
  164.  
  165. // dirty masks
  166. const ODULong kNotDirty                    = 0x0000UL;
  167. const ODULong kLinkDirty                = 0x0001UL;
  168. const ODULong kSourcePartDirty            = 0x0002UL;
  169. const ODULong kAutoUpdateDirty            = 0x0004UL;
  170. const ODULong kUpdateIDDirty            = 0x0008UL;
  171. const ODULong kChangeTimeDirty            = 0x0010UL;
  172. const ODULong kKindsUsedDirty            = 0x0020UL;
  173. const ODULong kContentSUDirty            = 0x0040UL;
  174. const ODULong kChangeLimitDirty            = 0x0080UL;
  175. const ODULong kAllDirty                    = 0xFFFFUL;
  176.  
  177. //==============================================================================
  178. // ODBaseLinkSource
  179. //==============================================================================
  180.  
  181. //------------------------------------------------------------------------------
  182. // ODBaseLinkSource: somInit
  183. //------------------------------------------------------------------------------
  184.  
  185. SOM_Scope void  SOMLINK ODBaseLinkSourcesomInit(ODBaseLinkSource *somSelf)
  186. {
  187.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  188.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","somInit");
  189.  
  190.     parent_somInit(somSelf);
  191.  
  192.     _fContentSU = (ODStorageUnit*) kODNULL;
  193.     _fLink = (ODLink*) kODNULL;
  194.     _fSourcePartSU = (ODStorageUnit*) kODNULL;
  195.     _fAutoUpdate = kODFalse;
  196.     _fNewUpdateID = kODUnknownUpdate;
  197.     _fUpdateID = kODUnknownUpdate;
  198.     _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  199.     _fChangeTime = 0;
  200.     _fChangeCount = 1;
  201.     _fChangeLimit = 1;
  202.     _fDirty = kNotDirty;
  203.     _fKindsUsed = (ODTypeList*) kODNULL;
  204.     _fCleared = kODFalse;
  205. }
  206.  
  207. //------------------------------------------------------------------------------
  208. // ODBaseLinkSource: somUninit
  209. //------------------------------------------------------------------------------
  210.  
  211. SOM_Scope void  SOMLINK ODBaseLinkSourcesomUninit(ODBaseLinkSource *somSelf)
  212. {
  213.     /* ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf); */
  214.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","somUninit");
  215.  
  216.     parent_somUninit(somSelf);
  217. }
  218.  
  219. //------------------------------------------------------------------------------
  220. // ODBaseLinkSource: InitBaseLinkSource
  221. //------------------------------------------------------------------------------
  222.  
  223. SOM_Scope void  SOMLINK ODBaseLinkSourceInitBaseLinkSource(ODBaseLinkSource *somSelf, Environment *ev,
  224.         ODStorageUnit* storageUnit,
  225.         ODPart* sourcePart)
  226. {
  227.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  228.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","InitBaseLinkSource");
  229.  
  230.     SOM_TRY
  231.  
  232.     somSelf->InitPersistentObject(ev, storageUnit);
  233.     InitDateInfo(ev, storageUnit);
  234.  
  235.     _fUpdateID = storageUnit->GetSession(ev)->UniqueUpdateID(ev);
  236.  
  237.     _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  238.  
  239.     if ( sourcePart != (ODPart*) kODNULL )
  240.     {
  241.         _fSourcePartSU = sourcePart->GetStorageUnit(ev);
  242.         _fSourcePartSU->Acquire(ev);
  243.         _fAutoUpdate = kODTrue;
  244.     }
  245.  
  246.     ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  247.  
  248.     _fContentSU = su->GetDraft(ev)->CreateStorageUnit(ev);
  249.     ODSetISOStrProp(ev, _fContentSU, kODPropStorageUnitType, kODISOStr, kODLinkContent);
  250.  
  251.     ODSUAddPropValue(ev, su, kODPropUpdateID, kODULong);
  252.     ODSUAddPropValue(ev, su, kODPropChangeLimit, kODULong);
  253.     ODSUAddPropValue(ev, su, kODPropChangeTime, kODTime_T);
  254.     ODSUAddPropValue(ev, su, kODPropAutoUpdate, kODBoolean);
  255.     ODSUAddPropValue(ev, su, kODPropLinkContentSU, kODStrongStorageUnitRef);
  256.     ODSUAddPropValue(ev, su, kODPropLink, kODWeakStorageUnitRef);
  257.  
  258.     if ( _fSourcePartSU != (ODStorageUnit*) kODNULL )
  259.         ODSUAddPropValue(ev, su, kODPropSourcePart, kODWeakStorageUnitRef);
  260.  
  261.     somSelf->SetBaseLinkSourceDirty(ev, kAllDirty);
  262.  
  263.     SOM_CATCH_ALL
  264.     SOM_ENDTRY
  265. }
  266.  
  267. //------------------------------------------------------------------------------
  268. // ODBaseLinkSource: InitBaseLinkSourceFromStorage
  269. //------------------------------------------------------------------------------
  270.  
  271. SOM_Scope void  SOMLINK ODBaseLinkSourceInitBaseLinkSourceFromStorage(ODBaseLinkSource *somSelf, Environment *ev,
  272.         ODStorageUnit* storageUnit)
  273. {
  274.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  275.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","InitBaseLinkSourceFromStorage");
  276.  
  277.     SOM_TRY
  278.  
  279.     somSelf->InitPersistentObjectFromStorage(ev, storageUnit);
  280.     InitDateInfo(ev, storageUnit);
  281.  
  282.     _fContentSU = storageUnit->GetDraft(ev)->AcquireStorageUnit(ev, ODGetStrongSURefProp(ev, storageUnit, kODPropLinkContentSU, kODStrongStorageUnitRef));
  283.     _fUpdateID = ODGetULongProp(ev, storageUnit, kODPropUpdateID, kODULong);
  284.     _fChangeLimit = ODGetULongProp(ev, storageUnit, kODPropChangeLimit, kODULong);
  285.     _fChangeTime = ODGetTime_TProp(ev, storageUnit, kODPropChangeTime, kODTime_T);
  286.     _fAutoUpdate = ODGetBooleanProp(ev, storageUnit, kODPropAutoUpdate, kODBoolean);
  287.  
  288.     _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  289.  
  290.     if ( storageUnit->Exists(ev, kODPropContentKindsUsed, 0, 0) )
  291.     {
  292.         _fKindsUsed = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetStorageSystem(ev)->CreateTypeList(ev, kODNULL);
  293.         ODGetTypeListProp(ev, storageUnit, kODPropContentKindsUsed, kODISOStrList, _fKindsUsed);
  294.     }
  295.  
  296.     if ( storageUnit->Exists(ev, kODPropLink, 0, 0) )
  297.     {
  298.         ODID linkID = ODGetWeakSURefProp(ev, storageUnit, kODPropLink, kODWeakStorageUnitRef);
  299.         if ( linkID == kODNULLID )
  300.             somSelf->SetBaseLinkSourceDirty(ev, kLinkDirty);
  301.         else
  302.             _fLink = storageUnit->GetDraft(ev)->AcquireLink(ev, linkID, (ODLinkSpec*) kODNULL);
  303.     }
  304.  
  305.     if ( storageUnit->Exists(ev, kODPropSourcePart, 0, 0) )
  306.     {
  307.         ODID sourcePartID = ODGetWeakSURefProp(ev, storageUnit, kODPropSourcePart, kODWeakStorageUnitRef);
  308.         if ( sourcePartID == kODNULLID )
  309.             somSelf->SetBaseLinkSourceDirty(ev, kSourcePartDirty);
  310.         else
  311.             _fSourcePartSU = storageUnit->GetDraft(ev)->AcquireStorageUnit(ev, sourcePartID);
  312.     }
  313.  
  314.     SOM_CATCH_ALL
  315.     SOM_ENDTRY
  316. }
  317.  
  318. //------------------------------------------------------------------------------
  319. // ODBaseLinkSource::Externalize (OVERRIDE)
  320. //------------------------------------------------------------------------------
  321.  
  322. SOM_Scope void  SOMLINK ODBaseLinkSourceExternalize(ODBaseLinkSource *somSelf, Environment *ev)
  323. {
  324.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  325.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Externalize");
  326.  
  327.     SOM_TRY
  328.  
  329.     parent_Externalize(somSelf,ev);
  330.  
  331.     _fContentSU->ClearAllPromises(ev);
  332.  
  333.     if ( _fDirty )
  334.     {
  335.         ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  336.  
  337.         if ( _fDirty & kContentSUDirty )
  338.             ODSetStrongSURefProp(ev, su, kODPropLinkContentSU, kODStrongStorageUnitRef, _fContentSU->GetID(ev));
  339.  
  340.         if ( _fDirty & kUpdateIDDirty )
  341.             ODSetULongProp(ev, su, kODPropUpdateID, kODULong, _fUpdateID);
  342.  
  343.         if ( _fDirty & kChangeLimitDirty )
  344.             ODSetULongProp(ev, su, kODPropChangeLimit, kODULong, _fChangeLimit);
  345.  
  346.         if ( _fDirty & kChangeTimeDirty )
  347.             ODSetTime_TProp(ev, su, kODPropChangeTime, kODTime_T, _fChangeTime);
  348.  
  349.         if ( _fDirty & kAutoUpdateDirty )
  350.             ODSetBooleanProp(ev, su, kODPropAutoUpdate, kODBoolean, _fAutoUpdate);
  351.     
  352.         if ( _fDirty & kKindsUsedDirty )
  353.         {
  354.             if ( _fKindsUsed == kODNULL )
  355.                 ODSURemoveProperty(ev, su, kODPropContentKindsUsed);
  356.             else
  357.                 ODSetTypeListProp(ev, su, kODPropContentKindsUsed, kODISOStrList, _fKindsUsed);
  358.         }
  359.         
  360.         if ( _fDirty & kLinkDirty )
  361.         {
  362.             if ( _fLink == (ODLink*) kODNULL )
  363.                 ODSURemoveProperty(ev, su, kODPropLink);
  364.             else
  365.                 ODSetWeakSURefProp(ev, su, kODPropLink, kODWeakStorageUnitRef, _fLink->GetStorageUnit(ev)->GetID(ev));
  366.         }
  367.  
  368.         if ( _fDirty & kSourcePartDirty )
  369.         {
  370.             if ( _fSourcePartSU == (ODStorageUnit*) kODNULL )
  371.                 ODSURemoveProperty(ev, su, kODPropSourcePart);
  372.             else
  373.                 ODSetWeakSURefProp(ev, su, kODPropSourcePart, kODWeakStorageUnitRef, _fSourcePartSU->GetID(ev));
  374.         }
  375.  
  376.         _fDirty = kNotDirty;
  377.     }
  378.  
  379.     SOM_CATCH_ALL
  380.     SOM_ENDTRY
  381. }
  382.  
  383. //------------------------------------------------------------------------------
  384. // ODBaseLinkSource: CloneInto (OVERRIDE)
  385. //------------------------------------------------------------------------------
  386.  
  387. SOM_Scope void  SOMLINK ODBaseLinkSourceCloneInto(ODBaseLinkSource *somSelf, Environment *ev,
  388.         ODDraftKey key,
  389.         ODStorageUnit* toSU,
  390.         ODFrame* scopeFrame)
  391. {
  392.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  393.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","CloneInto");
  394.  
  395.     SOM_TRY
  396.     
  397.     // If one of our properties already exists, this object has been cloned already
  398.     if ( toSU->Exists(ev, kODPropLink, kODWeakStorageUnitRef, 0) )
  399.         return;
  400.  
  401.     parent_CloneInto(somSelf, ev, key, toSU, scopeFrame);
  402.  
  403.     _fContentSU->ClearAllPromises(ev);
  404.  
  405.     CloneDateInfo(ev, somSelf->GetStorageUnit(ev), toSU);
  406.     
  407.     ODDraft* draft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  408.  
  409.     ODSetULongProp(ev, toSU, kODPropUpdateID, kODULong, _fUpdateID);
  410.     ODSetULongProp(ev, toSU, kODPropChangeLimit, kODULong, 1);
  411.     ODSetTime_TProp(ev, toSU, kODPropChangeTime, kODTime_T, _fChangeTime);
  412.     ODSetBooleanProp(ev, toSU, kODPropAutoUpdate, kODBoolean, _fAutoUpdate);
  413.  
  414.     ODID clonedLinkContentID = draft->Clone(ev, key, _fContentSU->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  415.     ODSetStrongSURefProp(ev, toSU, kODPropLinkContentSU, kODStrongStorageUnitRef, clonedLinkContentID);
  416.  
  417.     if ( _fKindsUsed != kODNULL )
  418.         ODSetTypeListProp(ev, toSU, kODPropContentKindsUsed, kODISOStrList, _fKindsUsed);
  419.  
  420.     if ( _fLink != (ODLink*) kODNULL )
  421.     {
  422.         ODID clonedLinkSourceID = draft->WeakClone(ev, key, _fLink->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  423.         ODSetWeakSURefProp(ev, toSU, kODPropLink, kODWeakStorageUnitRef, clonedLinkSourceID);
  424.     }
  425.  
  426.     // The source part should only be kODNULL for links imported from another draft.
  427.     if ( _fSourcePartSU != (ODStorageUnit*) kODNULL )
  428.     {
  429.         ODID clonedSourcePartID = draft->WeakClone(ev, key, _fSourcePartSU->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  430.         ODSetWeakSURefProp(ev, toSU, kODPropSourcePart, kODWeakStorageUnitRef, clonedSourcePartID);
  431.     }
  432.  
  433.     SOM_CATCH_ALL
  434.     SOM_ENDTRY
  435. }
  436.  
  437. //------------------------------------------------------------------------------
  438. // ODBaseLinkSource: ReleaseAll (OVERRIDE)
  439. //------------------------------------------------------------------------------
  440.  
  441. SOM_Scope void  SOMLINK ODBaseLinkSourceReleaseAll(ODBaseLinkSource *somSelf, Environment *ev)
  442. {
  443.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  444.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ReleaseAll");
  445.  
  446.     SOM_TRY
  447.  
  448.     parent_ReleaseAll(somSelf,ev);
  449.  
  450.     ODReleaseObject(ev, _fContentSU);
  451.     ODReleaseObject(ev, _fLink);
  452.     ODReleaseObject(ev, _fSourcePartSU);
  453.  
  454.     SOM_CATCH_ALL
  455.     SOM_ENDTRY
  456. }
  457.  
  458. //------------------------------------------------------------------------------
  459. // ODBaseLinkSource: SetBaseLinkSourceDirty
  460. //------------------------------------------------------------------------------
  461.  
  462. SOM_Scope void  SOMLINK ODBaseLinkSourceSetBaseLinkSourceDirty(ODBaseLinkSource *somSelf, Environment *ev,
  463.     ODULong dirtyProperty)
  464. {
  465.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  466.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetBaseLinkSourceDirty");
  467.  
  468.     SOM_TRY    
  469.         _fDirty |= dirtyProperty;
  470.  
  471.         ODDraft* draft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  472.         if ( draft->GetPermissions(ev) != kODDPReadOnly )
  473.             draft->SetChangedFromPrev(ev);
  474.     SOM_CATCH_ALL
  475.     SOM_ENDTRY
  476. }
  477.  
  478. //------------------------------------------------------------------------------
  479. // ODBaseLinkSource: ShowLinkSourceInfo
  480. //------------------------------------------------------------------------------
  481.  
  482. SOM_Scope ODBoolean  SOMLINK ODBaseLinkSourceShowLinkSourceInfo(ODBaseLinkSource *somSelf, Environment *ev,
  483.         ODFacet* facet,
  484.         ODUpdateID change,
  485.         ODBoolean changesAllowed,
  486.         ODLinkInfoResult* infoResult)
  487. {
  488.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  489.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ShowLinkSourceInfo");
  490.  
  491.     ODBoolean result = kODFalse;
  492.  
  493.     SOM_TRY
  494.     
  495.     THROW_IF_NULL(facet, kODErrNullFacetInput);
  496.     THROW_IF_NULL(infoResult, kODErrNullLinkInfoResultInput);
  497.     THROW_IF_NULL(_fLink, kODErrBrokenLink);
  498.  
  499.     ODSession* session = somSelf->GetStorageUnit(ev)->GetSession(ev);
  500.     ODTypeToken modalFocus = session->Tokenize(ev, kODModalFocus);
  501.     ODArbitrator* arbitrator = session->GetArbitrator(ev);
  502.     TempODFrame currentOwner = arbitrator->AcquireFocusOwner(ev, modalFocus);
  503.  
  504.     if ( arbitrator->RequestFocus(ev, modalFocus, facet->GetFrame(ev)) )
  505.     {
  506.         infoResult->autoUpdate = _fAutoUpdate;
  507.     
  508.         session->GetWindowState(ev)->DeactivateFrontWindows(ev);
  509.  
  510.         result = ShowLinkSourceInfo(somSelf, change, changesAllowed, infoResult);
  511.  
  512.         session->GetWindowState(ev)->ActivateFrontWindows(ev);
  513.  
  514.         arbitrator->TransferFocus(ev, modalFocus, facet->GetFrame(ev), currentOwner);
  515.     }
  516.     else
  517.     {
  518.         SysBeep(2);
  519.     }
  520.     return result;
  521.  
  522.     SOM_CATCH_ALL
  523.     SOM_ENDTRY
  524.     return kODFalse;
  525. }
  526.  
  527. //------------------------------------------------------------------------------
  528. // ODBaseLinkSource: Lock
  529. //------------------------------------------------------------------------------
  530.  
  531. SOM_Scope ODBoolean  SOMLINK ODBaseLinkSourceLock(ODBaseLinkSource *somSelf, Environment *ev,
  532.         ODULong wait,
  533.         ODLinkKey* key)
  534. {
  535.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  536.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Lock");
  537.  
  538.     ODUnused(wait);
  539.  
  540.     if ( _fLink == (ODLink*) kODNULL )
  541.     {
  542.         ODSetSOMException(ev, kODErrBrokenLink);
  543.         return kODFalse;
  544.     }
  545.  
  546.     TRY    // Don't use SOM_TRY as we do _not_ want to return an exception!
  547.  
  548.     *key = (ODLinkKey) somSelf->GetStorageUnit(ev)->Lock(ev, 0);
  549.     
  550.     _fCleared = kODFalse;
  551.     _fNewUpdateID = kODUnknownUpdate;
  552.     
  553.     CATCH_ALL
  554.         *key = kODNullKey;
  555.         // Don't reraise, just return
  556.     ENDTRY
  557.  
  558.     return (*key != kODNullKey);
  559. }
  560.  
  561. //------------------------------------------------------------------------------
  562. // ODBaseLinkSource: Unlock
  563. //------------------------------------------------------------------------------
  564.  
  565. SOM_Scope void  SOMLINK ODBaseLinkSourceUnlock(ODBaseLinkSource *somSelf, Environment *ev,
  566.         ODLinkKey key)
  567. {
  568.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  569.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Unlock");
  570.  
  571.     SOM_TRY
  572.  
  573.         // Force fulfilling of promises for content kinds used by current destinations
  574.         if ( _fCleared && _fKindsUsed )
  575.         {
  576.             ODBoolean allUsedKindsPresent = kODTrue; ODVolatile(allUsedKindsPresent);
  577.         
  578.             ODTypeListIterator* iter = kODNULL; ODVolatile(iter);
  579.             TRY
  580.                 iter = _fKindsUsed->CreateTypeListIterator(ev);
  581.         
  582.                 for (ODType kind = iter->First(ev);
  583.                     iter->IsNotComplete(ev);
  584.                     kind = iter->Next(ev))
  585.                 {
  586.                     if ( ODSUExistsThenFocus(ev, _fContentSU, kODPropContents, kind) )
  587.                     {
  588.                         if ( _fContentSU->IsPromiseValue(ev) )
  589.                         {
  590.                             // Force part to fulfill its promise
  591.                             TRY
  592.                                 ODULong size = _fContentSU->GetSize(ev);
  593.                             CATCH_ALL
  594.                                 allUsedKindsPresent = kODFalse;
  595.                             ENDTRY
  596.                         }
  597.                     }
  598.                     else
  599.                     {
  600.                         allUsedKindsPresent = kODFalse;
  601.                     }
  602.                     ODDisposePtr(kind);
  603.                 }
  604.             CATCH_ALL
  605.                 allUsedKindsPresent = kODFalse;
  606.             ENDTRY
  607.             ODDeleteObject(iter);
  608.         
  609.             if ( allUsedKindsPresent )
  610.             {
  611.                 ODDeleteObject(_fKindsUsed);
  612.                 somSelf->SetBaseLinkSourceDirty(ev, kKindsUsedDirty);
  613.             }
  614.         }
  615.  
  616.         _fCleared = kODFalse;
  617.  
  618.         // Any unlocking action needs to be performed before calling UpdateDependents(),
  619.         // since that will cause dependents to lock and unlock their link, which delegates
  620.         // to this object. 
  621.     
  622.         somSelf->GetStorageUnit(ev)->Unlock(ev, (ODStorageUnitKey) key);
  623.     
  624.         if ( _fNewUpdateID != kODUnknownUpdate )
  625.         {
  626.             ODBoolean notifyDependents = kODFalse;
  627.     
  628.             time(&_fChangeTime);
  629.             somSelf->SetBaseLinkSourceDirty(ev, kChangeTimeDirty);
  630.  
  631.             if ( _fUpdateID != _fNewUpdateID )
  632.             {
  633.                 // Link updated with different change ID than last time
  634.                 _fChangeCount = 1;
  635.                 _fUpdateID = _fNewUpdateID;
  636.                 somSelf->SetBaseLinkSourceDirty(ev, kUpdateIDDirty);
  637.                 notifyDependents = kODTrue;
  638.                 
  639.                 if ( _fSuspended )
  640.                     _fUpdatedAfterSuspended = kODTrue;
  641.             }
  642.             else if ( ++_fChangeCount <= _fChangeLimit )
  643.             {
  644.                 // Same change but user previously continued beyond this iteration
  645.                 notifyDependents = kODTrue;
  646.             }
  647.             else
  648.             {
  649.                 ODLinkManager* linkMgr = 
  650.                     somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  651.                 ODLinkUpdateResult updateResult = linkMgr->ShowLinkUpdateAlert(ev, somSelf);
  652.                     
  653.                 if ( updateResult == kODLinkUpdateContinue )
  654.                 {
  655.                     // User continued propagating this update
  656.                     ++_fChangeLimit;
  657.                     somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  658.                     notifyDependents = kODTrue;
  659.                 }
  660.                 else if ( updateResult == kODLinkUpdateStop )
  661.                 {
  662.                     // User cancelled propagating this update
  663.                     _fChangeLimit = 1;
  664.                     somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  665.                 }
  666.                 else // updateResult == kODLinkUpdateSuspend
  667.                 {
  668.                     _fSuspended = kODTrue;
  669.                 }
  670.             }
  671.     
  672.             _fNewUpdateID = kODUnknownUpdate;
  673.     
  674.             if ( notifyDependents && !_fSuspended && (_fLink != (ODLink*) kODNULL) )
  675.             {
  676.                 // Ignore errors returned by UpdateDependents
  677.                 TRY
  678.                     _fLink->UpdateDependents(ev);
  679.                 CATCH_ALL
  680.                 ENDTRY
  681.             }
  682.         }
  683.     
  684.     SOM_CATCH_ALL
  685.     
  686.     SOM_ENDTRY
  687. }
  688.  
  689.  
  690. //------------------------------------------------------------------------------
  691. // ODBaseLinkSource: LinkUpdateAlertCompleted
  692. //------------------------------------------------------------------------------
  693.  
  694. SOM_Scope void  SOMLINK ODBaseLinkSourceLinkUpdateAlertCompleted(ODBaseLinkSource *somSelf, Environment *ev,
  695.         ODLinkUpdateResult updateResult)
  696. {
  697.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  698.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","LinkUpdateAlertCompleted");
  699.  
  700.     ODBoolean notifyDependents = kODFalse;
  701.     
  702.     SOM_TRY
  703.     
  704.         // Get and reset these booleans atomically here to avoid possible 
  705.         // confusion from setting them again while updating dependents:
  706.         ODBoolean suspended = _fSuspended;
  707.         ODBoolean updatedAfterSuspended = _fUpdatedAfterSuspended;
  708.         _fSuspended = _fUpdatedAfterSuspended = kODFalse;
  709.         
  710.         if ( updateResult == kODLinkUpdateContinue )
  711.         {
  712.             // User continued propagating this update
  713.             ++_fChangeLimit;
  714.             somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  715.             notifyDependents = kODTrue;
  716.         }
  717.         else if ( updateResult == kODLinkUpdateStop )
  718.         {
  719.             // User cancelled propagating this update
  720.             _fChangeLimit = 1;
  721.             somSelf->SetBaseLinkSourceDirty(ev, kChangeLimitDirty);
  722.             
  723.             if ( updatedAfterSuspended )
  724.                 notifyDependents = kODTrue;
  725.         }
  726.  
  727.         if ( notifyDependents && (_fLink != (ODLink*) kODNULL) )
  728.         {
  729.             // Ignore errors returned by UpdateDependents
  730.             TRY
  731.                 _fLink->UpdateDependents(ev);
  732.             CATCH_ALL
  733.             ENDTRY
  734.         }
  735.  
  736.     SOM_CATCH_ALL
  737.     
  738.     SOM_ENDTRY
  739. }
  740.  
  741. //------------------------------------------------------------------------------
  742. // ODBaseLinkSource: KeyValid
  743. //------------------------------------------------------------------------------
  744.  
  745. SOM_Scope void  SOMLINK ODBaseLinkSourceKeyValid(ODBaseLinkSource *somSelf, Environment *ev,
  746.         ODLinkKey key)
  747. {
  748.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  749.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","KeyValid");
  750.  
  751.     SOM_TRY
  752.  
  753.     if (key == kODNullKey)
  754.         ODSetSOMException(ev, kODErrInvalidLinkKey);
  755.     else
  756.     {
  757.         ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  758.         ODStorageUnitKey suKey = su->Lock(ev, (ODStorageUnitKey) key);
  759.         su->Unlock(ev, suKey);
  760.     }
  761.  
  762.     SOM_CATCH_ALL
  763.     SOM_ENDTRY
  764. }
  765.  
  766. //------------------------------------------------------------------------------
  767. // ODBaseLinkSource: GetContentStorageUnit
  768. //------------------------------------------------------------------------------
  769.  
  770. SOM_Scope ODStorageUnit*  SOMLINK ODBaseLinkSourceGetContentStorageUnit(ODBaseLinkSource *somSelf, Environment *ev,
  771.         ODLinkKey key)
  772. {
  773.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  774.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetContentStorageUnit");
  775.  
  776.     SOM_TRY
  777.  
  778.     somSelf->KeyValid(ev, key);
  779.  
  780.     return _fContentSU;
  781.  
  782.     SOM_CATCH_ALL
  783.     SOM_ENDTRY
  784.     return (ODStorageUnit*) kODNULL;
  785. }
  786.  
  787. //------------------------------------------------------------------------------
  788. // ODBaseLinkSource: ContentUpdated
  789. //------------------------------------------------------------------------------
  790.  
  791. SOM_Scope void  SOMLINK ODBaseLinkSourceContentUpdated(ODBaseLinkSource *somSelf, Environment *ev,
  792.         ODUpdateID id,
  793.         ODLinkKey key)
  794. {
  795.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  796.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ContentUpdated");
  797.  
  798.     SOM_TRY
  799.  
  800.         somSelf->KeyValid(ev, key);
  801.  
  802.         if ( id == kODUnknownUpdate )
  803.             THROW(kODErrUnknownUpdateID);
  804.  
  805.         _fNewUpdateID = id;
  806.     
  807.     SOM_CATCH_ALL
  808.     
  809.     SOM_ENDTRY
  810. }
  811.  
  812. //------------------------------------------------------------------------------
  813. // ODBaseLinkSource: Clear
  814. //------------------------------------------------------------------------------
  815.  
  816. SOM_Scope void  SOMLINK ODBaseLinkSourceClear(ODBaseLinkSource *somSelf, Environment *ev,
  817.         ODUpdateID id,
  818.         ODLinkKey key)
  819. {
  820.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  821.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","Clear");
  822.  
  823.     ODValueType kind = kODNULL;    ODVolatile(kind);
  824.  
  825.     SOM_TRY
  826.  
  827.         somSelf->KeyValid(ev, key);
  828.  
  829.         // Fail immediately if this draft can't be changed
  830.         ODDraftPermissions permissions = somSelf->GetStorageUnit(ev)->GetDraft(ev)->GetPermissions(ev);
  831.         if (!HAS_WRITE_ACCESS(permissions))
  832.             THROW(kODErrInvalidPermissions);
  833.  
  834.         if ( id == kODUnknownUpdate )
  835.             THROW(kODErrUnknownUpdateID);
  836.  
  837.         // If id is the current id, don't notify destinations unless ContentUpdated is called.
  838.         if ( id != _fUpdateID )
  839.             _fNewUpdateID = id;
  840.         
  841.         // Add each non-promise value type in the contents property to _fKindsUsed,
  842.         // then remove the contents property.
  843.         if (ODSUExistsThenFocus(ev, _fContentSU, kODPropContents, kODNULL) )
  844.         {
  845.             ODULong numValues = _fContentSU->CountValues(ev);    
  846.             ODULong kindIndex;
  847.             
  848.             for (kindIndex = 0; kindIndex < numValues; kindIndex++)
  849.             {
  850.                 _fContentSU->Focus(ev, kODPropContents, kODPosUndefined, kODTypeAll, 0, kODPosNextSib);
  851.                 if ( !_fContentSU->IsPromiseValue(ev) )
  852.                 {
  853.                     if ( _fKindsUsed == kODNULL )
  854.                         _fKindsUsed = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetStorageSystem(ev)
  855.                                         ->CreateTypeList(ev, kODNULL);
  856.                     kind = _fContentSU->GetType(ev);
  857.                     _fKindsUsed->AddLast(ev, kind);
  858.                     ODDisposePtr(kind);
  859.                     kind = kODNULL;
  860.                     somSelf->SetBaseLinkSourceDirty(ev, kKindsUsedDirty);
  861.                 }
  862.             }
  863.  
  864.             ODSURemoveProperty(ev, _fContentSU, kODPropContents);
  865.  
  866.             RemoveDataInterchangeProperties(ev, _fContentSU, kODFalse);
  867.             
  868.             _fCleared = kODTrue;
  869.         }
  870.  
  871.     SOM_CATCH_ALL
  872.     
  873.         ODDisposePtr(kind);
  874.  
  875.     SOM_ENDTRY
  876. }
  877.  
  878. //------------------------------------------------------------------------------
  879. // ODBaseLinkSource: GetUpdateID
  880. //------------------------------------------------------------------------------
  881.  
  882. SOM_Scope ODUpdateID  SOMLINK ODBaseLinkSourceGetUpdateID(ODBaseLinkSource *somSelf, Environment *ev)
  883. {
  884.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  885.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetUpdateID");
  886.  
  887.     return _fUpdateID;
  888. }
  889.  
  890. //------------------------------------------------------------------------------
  891. // ODBaseLinkSource: SetUpdateID
  892. //------------------------------------------------------------------------------
  893.  
  894. SOM_Scope void  SOMLINK ODBaseLinkSourceSetUpdateID(ODBaseLinkSource *somSelf, Environment *ev,
  895.         ODUpdateID updateID,
  896.         ODLinkKey key)
  897. {
  898.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  899.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetUpdateID");
  900.  
  901.     SOM_TRY
  902.  
  903.     somSelf->KeyValid(ev, key);
  904.  
  905.     if ( updateID != _fUpdateID )
  906.     {
  907.         _fUpdateID = updateID;
  908.         somSelf->SetBaseLinkSourceDirty(ev, kUpdateIDDirty);
  909.     }
  910.  
  911.     SOM_CATCH_ALL
  912.     SOM_ENDTRY
  913. }
  914.  
  915. //------------------------------------------------------------------------------
  916. // ODBaseLinkSource: GetChangeTime
  917. //------------------------------------------------------------------------------
  918.  
  919. SOM_Scope ODTime  SOMLINK ODBaseLinkSourceGetChangeTime(ODBaseLinkSource *somSelf, Environment *ev)
  920. {
  921.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  922.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetChangeTime");
  923.  
  924.     return _fChangeTime;
  925. }
  926.  
  927. //------------------------------------------------------------------------------
  928. // ODBaseLinkSource: SetChangeTime
  929. //------------------------------------------------------------------------------
  930.  
  931. SOM_Scope void  SOMLINK ODBaseLinkSourceSetChangeTime(ODBaseLinkSource *somSelf, Environment *ev,
  932.         ODTime changeTime,
  933.         ODLinkKey key)
  934. {
  935.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  936.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetChangeTime");
  937.  
  938.     SOM_TRY
  939.  
  940.     somSelf->KeyValid(ev, key);
  941.  
  942.     _fChangeTime = changeTime;
  943.     somSelf->SetBaseLinkSourceDirty(ev, kChangeTimeDirty);
  944.  
  945.     SOM_CATCH_ALL
  946.     SOM_ENDTRY
  947. }
  948.  
  949. //------------------------------------------------------------------------------
  950. // ODBaseLinkSource: IsAutoUpdate
  951. //------------------------------------------------------------------------------
  952.  
  953. SOM_Scope ODBoolean  SOMLINK ODBaseLinkSourceIsAutoUpdate(ODBaseLinkSource *somSelf, Environment *ev)
  954. {
  955.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  956.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","IsAutoUpdate");
  957.  
  958.     return _fAutoUpdate;
  959. }
  960.  
  961. //------------------------------------------------------------------------------
  962. // ODBaseLinkSource: SetAutoUpdate
  963. //------------------------------------------------------------------------------
  964.  
  965. SOM_Scope void  SOMLINK ODBaseLinkSourceSetAutoUpdate(ODBaseLinkSource *somSelf, Environment *ev,
  966.         ODBoolean automatic)
  967. {
  968.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  969.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetAutoUpdate");
  970.  
  971.     SOM_TRY
  972.     _fAutoUpdate = automatic;
  973.     somSelf->SetBaseLinkSourceDirty(ev, kAutoUpdateDirty);
  974.     SOM_CATCH_ALL
  975.     SOM_ENDTRY
  976. }
  977.  
  978. //------------------------------------------------------------------------------
  979. // ODBaseLinkSource: GetLink
  980. //------------------------------------------------------------------------------
  981.  
  982. SOM_Scope ODLink*  SOMLINK ODBaseLinkSourceGetLink(ODBaseLinkSource *somSelf, Environment *ev)
  983. {
  984.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  985.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","GetLink");
  986.  
  987.     if ( _fLink == (ODLink*) kODNULL )
  988.     {
  989.         ODSetSOMException(ev, kODErrBrokenLink);
  990.         return (ODLink*) kODNULL;
  991.     }
  992.  
  993.     return _fLink;
  994. }
  995.  
  996. //------------------------------------------------------------------------------
  997. // ODBaseLinkSource: SetLink
  998. //------------------------------------------------------------------------------
  999.  
  1000. SOM_Scope void  SOMLINK ODBaseLinkSourceSetLink(ODBaseLinkSource *somSelf, Environment *ev,
  1001.         ODLink* link)
  1002. {
  1003.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1004.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetLink");
  1005.  
  1006.     SOM_TRY
  1007.     
  1008.     if ( !ODObjectsAreEqual(ev, _fLink, link) )
  1009.     {
  1010.         ODReleaseObject(ev, _fLink);
  1011.     
  1012.         _fLink = link;
  1013.         if ( _fLink != (ODLink*) kODNULL )
  1014.             _fLink->Acquire(ev);
  1015.  
  1016.         somSelf->SetBaseLinkSourceDirty(ev, kLinkDirty);
  1017.     }
  1018.     
  1019.     SOM_CATCH_ALL
  1020.     SOM_ENDTRY
  1021. }
  1022.  
  1023. //------------------------------------------------------------------------------
  1024. // ODBaseLinkSource: AcquireSourcePart
  1025. //------------------------------------------------------------------------------
  1026.  
  1027. SOM_Scope ODStorageUnit*  SOMLINK ODBaseLinkSourceAcquireSourcePart(ODBaseLinkSource *somSelf, Environment *ev)
  1028. {
  1029.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1030.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","AcquireSourcePart");
  1031.  
  1032.     if ( _fSourcePartSU != (ODStorageUnit*) kODNULL ) {
  1033.         SOM_TRY
  1034.         _fSourcePartSU->Acquire(ev);
  1035.         SOM_CATCH_ALL
  1036.         SOM_ENDTRY
  1037.     }
  1038.     return _fSourcePartSU;
  1039. }
  1040.  
  1041. //------------------------------------------------------------------------------
  1042. // ODBaseLinkSource: SetSourcePart
  1043. //------------------------------------------------------------------------------
  1044.  
  1045. SOM_Scope void  SOMLINK ODBaseLinkSourceSetSourcePart(ODBaseLinkSource *somSelf, Environment *ev,
  1046.         ODStorageUnit* sourcePartSU)
  1047. {
  1048.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1049.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","SetSourcePart");
  1050.  
  1051.     SOM_TRY
  1052.  
  1053.     if ( !ODObjectsAreEqual(ev, _fSourcePartSU, sourcePartSU) )
  1054.     {
  1055.         ODReleaseObject(ev, _fSourcePartSU);
  1056.     
  1057.         _fSourcePartSU = sourcePartSU;
  1058.         if ( _fSourcePartSU != (ODStorageUnit*) kODNULL )
  1059.             _fSourcePartSU->Acquire(ev);
  1060.     
  1061.         somSelf->SetBaseLinkSourceDirty(ev, kSourcePartDirty);
  1062.     }
  1063.  
  1064.     SOM_CATCH_ALL
  1065.     SOM_ENDTRY
  1066. }
  1067.  
  1068. //------------------------------------------------------------------------------
  1069. // ODBaseLinkSource: ShowSourceContent
  1070. //------------------------------------------------------------------------------
  1071.  
  1072. SOM_Scope void  SOMLINK ODBaseLinkSourceShowSourceContent(ODBaseLinkSource *somSelf, Environment *ev)
  1073. {
  1074.     ODBaseLinkSourceData *somThis = ODBaseLinkSourceGetData(somSelf);
  1075.     ODBaseLinkSourceMethodDebug("ODBaseLinkSource","ShowSourceContent");
  1076.  
  1077.     SOM_TRY
  1078.  
  1079.     if ( _fSourcePartSU == (ODStorageUnit*) kODNULL )
  1080.         THROW(kODErrBrokenLinkSource);
  1081.     
  1082.     TempODPart part = somSelf->GetStorageUnit(ev)->GetDraft(ev)->AcquirePart(ev, _fSourcePartSU->GetID(ev));
  1083.     part->RevealLink(ev, (ODLinkSource*) somSelf);
  1084.  
  1085.     SOM_CATCH_ALL
  1086.     SOM_ENDTRY
  1087. }
  1088.